﻿using BLevy.Datos.Interfases;
using BLevy.Entidad;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using DapperExtensions;
using System.Globalization;
using System.Threading;

namespace BLevy.Datos.Repositories
{
    public interface ICobradorCuponRepository : IRepository<CobradorCupon>
    {
        int EntradaSalidaCupones(CobradorCupon _cobradorCupon);
        IList<CobradorCupon> FindAllComplete();
        IList<CobradorCupon> FindAllCondicional(string numero_cupon, string certificado, int? cobrador_id, DateTime? desde, DateTime? hasta);
        IList<CobradorCupon> FindCuponesByCobrador(int idCobrador);
        CobradorCupon FindUltimaSalidaCupon(int cupon_id);

    }

    public class CobradorCuponRepository : ICobradorCuponRepository
    {
        protected readonly IDbConnection _db;

        public CobradorCuponRepository()
        {
            try
            {
                _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString());
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int EntradaSalidaCupones(CobradorCupon _cobradorCupon)
        {
            int resultado = 0;
            int resultadoCupon = 0;
            bool res = true;
            string query = "INSERT INTO COBRADORESCUPONES (COBRADOR_ID, CUPON_ID, FECHA, TIPO_MOVIMIENTO) " +
                            " VALUES (@cobrador_id, @cupon_id, @fecha, @tipo_movimiento);" +
                            "SELECT LAST_INSERT_ID();";

            string queryCupon = "UPDATE CUPONES SET TRANSITO = @transito WHERE ID = @cupon_id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    _db.Open();
                    //using (var tran = _db.BeginTransaction())
                    //{
                    try
                    {
                        //foreach (var c in cobradoresCuponesL)
                        //{
                        resultado = _db.Query<int>(query, new
                        {
                            cobrador_id = _cobradorCupon.cobrador_id,
                            cupon_id = _cobradorCupon.cupon_id,
                            fecha = _cobradorCupon.fecha.ToString("yyyy-MM-dd  HH:mm:ss"),
                            tipo_movimiento = _cobradorCupon.tipo_movimiento
                        }).Single();

                        if (resultado == 0)
                        {
                            res = false;
                            //break;
                        }
                        else
                        {
                            resultadoCupon = _db.Execute(queryCupon, new
                            {
                                transito = _cobradorCupon.tipo_movimiento,
                                cupon_id = _cobradorCupon.cupon_id
                            });

                            if (resultadoCupon == 0)
                            {
                                res = false;
                                //break;
                            }
                        }
                        //}

                        if (res == false)
                        {
                            resultado = 0;
                        }

                        return resultado;
                    }
                    catch
                    {
                        //tran.Rollback();
                        resultado = 0;

                        return resultado;
                    }
                    //}
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public int EntradaCupones(CobradorCupon _cobradorCupon)
        {
            int resultado = 0;
            int resultadoCupon = 0;
            bool res = true;
            string query = "INSERT INTO COBRADORESCUPONES (COBRADOR_ID, CUPON_ID, FECHA, TIPO_MOVIMIENTO) " +
                            " VALUES (@cobrador_id, @cupon_id, @fecha, @tipo_movimiento)";

            string queryCupon = "UPDATE CUPONES SET TRANSITO = @transito WHERE ID = @cupon_id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    _db.Open();
                    using (var tran = _db.BeginTransaction())
                    {
                        try
                        {
                            resultado = _db.Execute(query, new
                            {
                                cobrador_id = _cobradorCupon.cobrador_id,
                                cupon_id = _cobradorCupon.cupon_id,
                                fecha = _cobradorCupon.fecha.ToString("yyyy-MM-dd  HH:mm:ss"),
                                tipo_movimiento = _cobradorCupon.tipo_movimiento
                            });

                            if (resultado == 0)
                            {
                                res = false;
                            }
                            else
                            {
                                resultadoCupon = _db.Execute(queryCupon, new
                                {
                                    transito = _cobradorCupon.tipo_movimiento,
                                    cupon_id = _cobradorCupon.cupon_id
                                });

                                if (resultadoCupon == 0)
                                {
                                    res = false;
                                }
                            }

                            if (res == true)
                            {
                                tran.Commit();
                            }
                            else
                            {
                                tran.Rollback();
                                resultado = 0;
                            }

                            return resultado;
                        }
                        catch
                        {
                            tran.Rollback();
                            resultado = 0;

                            return resultado;
                        }
                    }
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public IList<CobradorCupon> FindAll()
        {
            throw new NotImplementedException();
        }

        public IQueryable<CobradorCupon> Find(System.Linq.Expressions.Expression<Func<CobradorCupon, bool>> predicate)
        {
            throw new NotImplementedException();
        }

        public CobradorCupon FindById(int id)
        {
            throw new NotImplementedException();
        }

        public int Add(CobradorCupon newEntity)
        {
            throw new NotImplementedException();
        }

        public int Remove(int id)
        {
            throw new NotImplementedException();
        }

        public int Modify(CobradorCupon entity)
        {
            throw new NotImplementedException();
        }

        public IList<CobradorCupon> FindAllComplete()
        {
            string query = "SELECT * FROM COBRADORESCUPONES " +
                "INNER JOIN COBRADORES ON COBRADORES.ID = COBRADORESCUPONES.COBRADOR_ID " +
                "INNER JOIN CUPONES ON CUPONES.ID = COBRADORESCUPONES.CUPON_ID " +
                "INNER JOIN SOCIOS ON SOCIOS.ID = CUPONES.SOCIO_ID " +  
                "ORDER BY COBRADORESCUPONES.FECHA_SALIDA DESC";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<CobradorCupon, Cobrador, Cupon, Socio, CobradorCupon>(query,
                        (cobrador_cupon, cobrador, cupon, socio) =>
                        {
                            cobrador_cupon.cobrador = cobrador;
                            cobrador_cupon.cupon = cupon;
                            cupon.socio = socio;
                            return cobrador_cupon;
                        }, splitOn: "id").ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }


        public IList<CobradorCupon> FindAllCondicional(string numero_cupon, string certificado, int? cobrador_id, DateTime? desde, DateTime? hasta)
        {
            string query = "SELECT * FROM COBRADORESCUPONES " +
                "INNER JOIN COBRADORES ON COBRADORES.ID = COBRADORESCUPONES.COBRADOR_ID " +
                "INNER JOIN CUPONES ON CUPONES.ID = COBRADORESCUPONES.CUPON_ID " +
                "INNER JOIN SOCIOS ON SOCIOS.ID = CUPONES.SOCIO_ID " +
                "WHERE ((CUPONES.NUMERO LIKE CONCAT('%', @numero_cupon, '%')) OR (@numero_cupon IS NULL)) " + 
                "AND ((SOCIOS.NUMERO_CERTIFICADO LIKE CONCAT('%', @certificado, '%')) OR (@certificado IS NULL)) " + 
                "AND ((COBRADORESCUPONES.COBRADOR_ID = @cobrador_id) OR (@cobrador_id IS NULL)) " + 
                "AND ((COBRADORESCUPONES.FECHA BETWEEN @desde AND @hasta) OR ((@desde IS NULL) OR (@hasta IS NULL))) " + 
                "ORDER BY COBRADORESCUPONES.FECHA DESC";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<CobradorCupon, Cobrador, Cupon, Socio, CobradorCupon>(query,
                        (cobrador_cupon, cobrador, cupon, socio) =>
                        {
                            cobrador_cupon.cobrador = cobrador;
                            cobrador_cupon.cupon = cupon;
                            cupon.socio = socio;
                            return cobrador_cupon;
                        }, new
                        {
                            numero_cupon = numero_cupon,
                            certificado = certificado,
                            cobrador_id = cobrador_id,
                            desde = desde,
                            hasta = hasta
                        }, splitOn: "id").ToList();
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public IList<CobradorCupon> FindCuponesByCobrador(int idCobrador)
        {
            string query = "SELECT * FROM COBRADORESCUPONES CC " +
                            "INNER JOIN COBRADORES O ON CC.cobrador_id = O.id " +
                            "INNER JOIN CUPONES C ON CC.cupon_id = C.id " +
                            "INNER JOIN SOCIOS S ON C.socio_id = S.id " +
                            "WHERE (C.estado = 'I' AND C.transito = 'E' AND CC.tipo_movimiento = 'E') " +
                            "AND CC.cobrador_id = @cobrador_id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    return _db.Query<CobradorCupon, Cobrador, Cupon, Socio, CobradorCupon>(query,
                        (cobrador_cupon, cobrador, cupon, socio) =>
                        {
                            cobrador_cupon.cobrador = cobrador;
                            cobrador_cupon.cupon = cupon;
                            cupon.socio = socio;
                            return cobrador_cupon;
                        }, new
                        {
                            cobrador_id = idCobrador
                        }, splitOn: "id").ToList();
                }
            }
            catch(Exception e)
            {
                throw e;
            }
        }

        public CobradorCupon FindUltimaSalidaCupon(int cupon_id)
        {
            DateTime ultima_salida;
            
            const string query = "SELECT MAX(FECHA) FROM COBRADORESCUPONES " +
                "WHERE CUPON_ID = @cupon_id AND TIPO_MOVIMIENTO = 'E'";

            const string query_cupon = "SELECT * FROM COBRADORESCUPONES " +
                "INNER JOIN COBRADORES ON COBRADORES.ID = COBRADORESCUPONES.COBRADOR_ID " +
                "INNER JOIN CUPONES ON CUPONES.ID = COBRADORESCUPONES.CUPON_ID " +
                "WHERE COBRADORESCUPONES.FECHA = @fecha_salida AND COBRADORESCUPONES.CUPON_ID = @cupon_id";

            try
            {
                using (IDbConnection _db = new MySqlConnection(ConfigurationManager.ConnectionStrings["LEVYDB"].ToString()))
                {
                    ultima_salida = _db.Query<DateTime>(query, new { cupon_id = cupon_id }).Single();

                    return _db.Query<CobradorCupon, Cobrador, Cupon, CobradorCupon>(query_cupon,
                        (cobrador_cupon, cobrador, cupon) =>
                        {
                            cobrador_cupon.cobrador = cobrador;
                            cobrador_cupon.cupon = cupon;
                            return cobrador_cupon;
                        }, new
                        {
                            fecha_salida = ultima_salida,
                            cupon_id = cupon_id
                        }, splitOn: "id").SingleOrDefault();
                }
            }
            catch(Exception e)
            { 
                throw e;
            }
        }




    }
}
